package com.vecspace.database.dao;

import java.io.Serializable;
import java.sql.Clob;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import com.vecspace.data.model.IPagination;
import com.vecspace.database.model.DataTable;
import com.vecspace.database.model.IDataRowMapper;
import com.vecspace.database.model.QueryResult;
import com.vecspace.database.model.QueryResultAggregation;
import com.vecspace.database.model.QuerySQL;

import comvecspace.data.model.sql.SqlDataType;

public interface DaoHelper {


	/**
	 * 
	 * 方法功能描述:插入一个对象 调用举例：insertObject(userInfo)userInfo为hibernate映射对象名称;
	 * 
	 * @param obj 传入的是该对象实体
	 * @throws Exception:void
	 */
	public void insertObject(Object obj) throws Exception;

	/**
	 * 
	 * 方法功能描述:修改一个对象 调用举例：updateObject(userInfo)userInfo为hibernate映射对象实例;
	 * 
	 * @param obj 传入的是该对象实体
	 * @throws Exception:void
	 */
	public void updateObject(Object obj) throws Exception;

	/**
	 * 
	 * 方法功能描述:删除一个对象
	 * 
	 * @param obj 如果是HIBERNATE技术则传入的是该对象实体
	 * @throws Exception:void
	 */
	public void deleteObject(Object obj) throws Exception;
	
	/**
	 * 
	 * 方法功能描述:删除一个对象 调用举例：deleteObject(UserInfo.class, 1)UserInfo为hibernate映射对象名称;
	 * 
	 * @param clazz 类
	 * @param id    对象对应ID
	 * @throws Exception:void
	 */
	public void deleteObject(Class<?> clazz, Serializable id) throws Exception;

	/**
	 * 
	 * 方法功能描述:删除多个对象 调用举例：deleteObject(list) list中的对象为hibernate映射对象;
	 * 
	 * @param list  list中的对象为hibernate映射对象
	 * @throws Exception:void
	 */
	public void deleteObjects(List<?> list) throws Exception;
	

	/**
	 * 
	 * 方法功能描述:更新或保持一个对象 调用举例：insertObject(userInfo)userInfo为hibernate映射对象名称;
	 * 
	 * @param obj 传入的是该对象实体
	 * @throws Exception:void
	 */
	public void saveOrUpdateObject(Object obj) throws Exception;
	
	/**
	 * 
	 * 方法功能描述:根据对象ID查询出该对象，该方法主要是由HIBERNATE技术使用 调用举例：getObject(UserInfo.class,
	 * 1)UserInfo为hibernate映射对象名称;
	 * 
	 * @param clazz
	 * @param id
	 * @return
	 * @throws Exception:Object
	 */
	public <T> T queryObject(Class<T> clazz, Serializable id) throws Exception;

	/**
	 * 方法功能描述：根据查询条件查询出该对象。 调用举例：getObject("from UserInfo u where u.name=:myName and
	 * u.password=:MyPassword",new String[]{"myName", "myPassword"},new
	 * String[]{"xiyue", "123″});;
	 * 
	 * @param1 查询语句
	 * @param2 参数名，HIBERNATE技术传输参数名
	 * @param3 参数值
	 * @return
	 */
	public <T> T queryObject(String hql, Object[] params) throws Exception;

	/**
	 * 方法功能描述：根据一条完整的标准sql语句查询出一个个对象。 调用举例：getDataRowByHSql("select b.* from b left
	 * outer join a on a.pid=b.id where b.id=?",new String[]{"100001"});
	 * 
	 * @param sql    一个完整的标准sql语句
	 * @param params sql中对应的参数值
	 * @return
	 * @throws Exception
	 */
	public <T> T queryObjectBySql(Class<T> clazz, String sql, Object[] params) throws Exception;
	
	/**
	 * 
	 * 方法功能描述:根据查询语句进行分页查询。 调用举例：getObjectCount(pageModel,"from
	 * UserInfo");UserInfo为hibernate映射类名称;
	 * 
	 * @param pageModel 保存分页结果对象
	 * @param hql       查询语句
	 * @return 返回的分页结果对象
	 * @throws Exception:PageModel
	 */
	public <T> QueryResult<T> queryObjectListByPage(String hql, IPagination pageModel) throws Exception;

	/**
	 * 
	 * 方法功能描述:根据查询语句进行非分页查询。 调用举例：getObjectCount("from
	 * UserInfo");UserInfo为hibernate映射类名称;
	 * 
	 * @param hql 查询语句
	 * @return 返回的查询结果
	 * @throws Exception:List
	 */
	public <T> List<T> queryObjectList(String hql) throws Exception;
	/**
	 * 方法功能描述:根据查询语句进行非分页查询。 调用举例：getObjectList("from UserInfo u where u.name=? and
	 * u.password=?,new String[]{"xiyue", "123″});;
	 * 
	 * @param hql
	 * @param params
	 * @return
	 * @throws Exception:List
	 */
	public <T> List<T> queryObjectList(String hql, Object[] params) throws Exception;
	
	/**
	 * 方法功能描述：根据查询语句进行非分页查询。 调用举例：getObjectList("from UserInfo u where
	 * u.name=:myName and u.password=:MyPassword",new String[]{"myName",
	 * "myPassword"},new String[]{"xiyue", "123″});;
	 * 
	 * @param1 查询语句
	 * @param2 参数名，HIBERNATE技术传输参数名
	 * @param3 参数值
	 * @return返回的分页结果对象
	 */
	public <T> List<T> queryObjectList(String hql, String[] paramNames, Object[] params) throws Exception;

	/**
	 * 方法功能描述：根据一条完整的标准sql语句查询出多个对象。 调用举例：getDataRowByHSql("select b.* from b left
	 * outer join a on a.pid=b.id where b.id=?",new String[]{"100001"});
	 * 
	 * @param sql    一个完整的标准sql语句
	 * @param params sql中对应的参数值
	 * @return
	 * @throws Exception
	 */
	public <T> List<T> queryObjectListBySql(Class<T> clazz, String sql, Object[] params) throws Exception;
	
	/**根据sql查询出JavaBean对象列表 <br>
	 * 1、根据sql查询出Map对象<br>
	 * 2.1、如果 T 为 Map，则返回Map对象列表<br>
	 * 2.2、否则，将Map对象转为JavaBean对象（根据JavaBean属性上的Column注解。有注解但sql中没有对应的列名，不会抛出异常）
	 * @param <T> JavaBean类
	 * @param clazz JavaBean类
	 * @param sql 查询sql，
	 * @param params sql参数
	 * @return
	 * @throws Exception 
	 * @author wanghua
	 * @reviewer  
	 * @createTime 2021年9月5日 下午9:55:00
	 */
	public <T> List<T> queryEntityListBySql(Class<T> clazz, String sql, Object[] params) throws Exception;
	
	/**
	 * 
	 * 方法功能描述: 根据查询语句进行分页查询。 调用举例：getObjectListByPage(pageModel,new
	 * String[]{"myName", "myPassword"},new String[]{"xiyue", "123″},"from UserInfo
	 * u where u.name=:myName and u.password=:MyPassword");UserInfo为hibernate映射类名称;
	 * 
	 * @param pageModel  保存分页结果对象
	 * @param paramNames 参数名，HIBERNATE技术传输参数名;
	 * @param params     参数值
	 * @param hql        查询语句
	 * @return 返回的分页结果对象
	 * @throws Exception:PageModel
	 */
	public <T> QueryResult<T> queryObjectListByPage(String hql, String[] paramNames, Object[] params, IPagination pagiation) throws Exception;

	/**
	 * 方法功能描述:根据查询语句进行分页查询。 调用举例：getObjectListByPage(pageModel,new String[]{"xiyue",
	 * "123″},"from UserInfo u where u.name=? and
	 * u.password=?");UserInfo为hibernate映射类名称;
	 * 
	 * @param pageModel
	 * @param params
	 * @param hql
	 * @return
	 * @throws Exception:PageModel
	 */
	public <T> QueryResult<T> queryObjectListByPage(String hql, Object[] params, IPagination pagiation) throws Exception;

	/**
	 * 方法功能描述：根据一条完整的标准sql语句查询出多个Hibernate对象(分页查询)。 调用举例：getDataRowByHSql("select b.*
	 * from b left outer join a on a.pid=b.id where b.id=?",new String[]{"100001"});
	 * 
	 * @param sql    一个完整的标准sql语句
	 * @param params sql中对应的参数值
	 * @return
	 * @throws Exception
	 */
	public <T> QueryResult<T> queryObjectPageBySql(Class<T> clazz, String sql, Object[] params, IPagination pagiation) throws Exception;

	/*-------------------------------------------------------以下为JDBC方式调用--------------------------------------------------------------*/


	public int insertDataRowBySql(String sql, Object[] params) throws Exception;

	/**
	 * 功能描述：通过SQL对数据库进行修改 调用举例：updateDataRowBySql("insert into
	 * emp(name,sex,pass,hiredate) values(?,?,?,?)", new Object[] { "张三", "男",
	 * "pass1","hiredate1" });
	 * 
	 * @param sql
	 * @param params
	 * @return
	 * @throws Exception
	 */
	public int updateDataRowBySql(String sql, Object[] params) throws Exception;
	
	/**
	 * 功能描述：通过SQL进行数据库批量修改 调用举例：batchUpdateDataRowBySql("insert into
	 * emp(name,sex,pass,hiredate) values(?,?,?,?)", new ArrayList().add(new
	 * Object[] { "张三", "男", "pass1","hiredate1" }));
	 * 
	 * @param sql
	 * @param batchArgs
	 * @return
	 * @throws Exception
	 */
	public int[] batchUpdateDataRowBySql(String sql, List<Object[]> batchArgs) throws Exception;

	/**
	 * 功能描述：通过SQL进行数据库批量修改，并返回主键 调用举例：batchUpdateReturnKey("insert into
	 * emp(name,sex,pass,hiredate) values(?,?,?,?)", new ArrayList().add(new
	 * Object[] { "张三", "男", "pass1","hiredate1" }));
	 * 
	 * @param sql
	 * @param params
	 * @return
	 * @throws Exception
	 */
	public List<Long> batchUpdateReturnKey(String sql, List<Object[]> params) throws Exception;

	/**
	 * 功能描述：通过SQL对数据库进行删除 调用举例：updateDataRowBySql("insert into
	 * emp(name,sex,pass,hiredate) values(?,?,?,?)", new Object[] { "张三", "男",
	 * "pass1","hiredate1" });
	 * 
	 * @param sql
	 * @param params
	 * @return
	 * @throws Exception
	 */
	public int deleteDataRowBySql(String sql, Object[] params) throws Exception;
	
	/**
	 * 方法功能描述:根据sql语句查询单挑记录，如果有多条数据，只返回第一条，如果没有记录，返回null 功能描述：
	 * 
	 * @param sql    查询语句 select userid,username from user where id=?
	 * @param params sql的参数值
	 * @return
	 * @throws Exception
	 */
	public Object[] queryDataRow(String sql, Object[] params) throws Exception;

	/**
	 * 
	 * 方法功能描述:根据查询语句进行非分页查询,jdbc模式。 调用举例：getDataRowsBySql("select 字段1,字段2 from
	 * User_Info")User_Info为数据库表名;
	 * 
	 * @param hql 查询语句
	 * @return 返回的查询结果,list中封装object数组
	 * @throws Exception:List
	 */
	public List<Object[]> queryDataRowList(String sql) throws Exception;

	/**
	 * 
	 * 方法功能描述:根据查询语句进行非分页查询,jdbc模式。 调用举例：getDataRowsCountBySql(new
	 * String[]{"xiyue", "123″},"select 字段1,字段2 from User_Info u where u.name=? and
	 * u.password=?")User_Info为数据库表名;
	 * 
	 * @param sql    查询语句
	 * @param params 参数值
	 * @return 返回list中封装object数组
	 * @throws Exception:List
	 */
	public List<Object[]> queryDataRowList(String sql, Object[] params) throws Exception;

	/**
	 * 
	 * 方法功能描述: 根据查询语句进行分页查询,jdbc模式。 调用举例：getDataRowsCountBySql(pageModel,"select
	 * 字段1,字段2 from User_Info")User_Info为数据库表名;
	 * 
	 * @param Sql       查询语句
	 * @param pageModel 保存分页结果对象
	 * @return 返回的分页结果对象
	 * @throws Exception:PageModel
	 */
	public QueryResult<Object[]> queryDataRowListByPage(String sql, IPagination pagination) throws Exception;
	
	/**
	 * 
	 * 方法功能描述:根据查询语句进行分页查询,jdbc模式。 调用举例：getDataRowsCountBySql(pageModel,new Object[]{"abc", "111"},"select 字段1,字段2 from User_Info u where u.name=? and u.password=?")User_Info为数据库表名;
	 * 
	 * @param Sql       查询语句
	 * @param pageModel 保存分页结果对象
	 * @return 返回的分页结果对象,list中封装object数组
	 * @throws Exception:PageModel
	 */
	public QueryResult<Object[]> queryDataRowListByPage(String sql, Object[] params, IPagination pagination) throws Exception;

	/**
	 * 获取一行记录(如果有多行，只返回第一行记录),返回map或者null
	 * 
	 * @param sql
	 * @param params sql参数值，可以为null
	 * @return
	 * @throws Exception
	 */
	public Map<String, Object> queryDataRowMap(String sql, Object[] params) throws Exception;

	/**
	 * 
	 * 方法功能描述:根据查询语句进行非分页查询,jdbc模式。 调用举例：getDataRowMapListBySql("select 字段1,字段2 from
	 * User_Info")User_Info为数据库表名;
	 * 
	 * @param hql 查询语句
	 * @return 返回的查询结果,list中封装Map对象
	 * @throws Exception:List
	 */
	public List<Map<String, Object>> queryDataRowMapList(String sql) throws Exception;
	
	/**
	 * 
	 * 方法功能描述:根据查询语句进行非分页查询,jdbc模式。
	 * 
	 * @param sql    查询语句
	 * @param params 参数值
	 * @return 返回的结果对象list中封装Map对象
	 * @throws Exception:List
	 */
	public List<Map<String, Object>> queryDataRowMapList(String sql, Object[] params) throws Exception;

	/**
	 * 
	 * 方法功能描述:根据查询语句进行分页查询,jdbc模式。 调用举例：getDataRowMapPageBySql(pageModel,new
	 * String[]{"xiyue", "123″},"select 字段1,字段2 from User_Info u where u.name=? and
	 * u.password=?")User_Info为数据库表名;
	 * 
	 * @param pageModel 保存分页结果对象
	 * @param params    参数值
	 * @param Sql       查询语句
	 * @return 返回的分页结果对象,list中封装Map对象
	 * @throws Exception:PageModel
	 */
	public QueryResult<Map<String, Object>> queryDataRowMapListByPage(String sql, Object[] params, IPagination pagination) throws Exception;

	/**
	 * 
	 * 方法功能描述: 根据查询语句进行分页查询,jdbc模式。 调用举例：getDataRowMapPageBySql(pageModel,"select
	 * 字段1,字段2 from User_Info")User_Info为数据库表名;
	 * 
	 * @param pageModel 保存分页结果对象
	 * @param Sql       查询语句
	 * @return 返回的分页结果对象,list中封装Map对象
	 * @throws Exception:PageModel
	 */
	public QueryResult<Map<String, Object>> queryDataRowMapListByPage(String sql, IPagination pagination) throws Exception;
	

	/**
	 * 
	 * 功能描述：调用存储过程
	 * 
	 * @param procedureName 存储过程名，如proc1
	 * @param params        存储过程参数列表 List<参数类型，参数值>
	 * @return
	 * @throws Exception
	 */
	public int callProcedure(String procedureName, List<String[]> params) throws Exception;

	/**
	 * 
	 * 功能描述：
	 * 
	 * @param sql
	 * @param params
	 * @param pageIndex 从1开始
	 * @param pageSize
	 * @return
	 */
	public DataTable queryDataTable(String sql, Object[] params) throws Exception;
	
	/**
	 * 
	 * 功能描述：
	 * 
	 * @param sql
	 * @param params
	 * @param pageIndex 从1开始
	 * @param pageSize
	 * @return
	 */
	public DataTable queryDataTable(String sql, Object[] params, int pageIndex, int pageSize) throws Exception;


	/**
	 * 返回表字段的数据类型 Map<String, Integer> --> Map<字段名（小写）, java.sql.Types>
	 * 
	 * @param tableName
	 * @return
	 * @throws SQLException
	 */
	public Map<String, SqlDataType> queryColumnsType(String tableName) throws SQLException;

	/**
	 * 获取第一行第一列的值
	 * 
	 * @param sql "select field_name from table where ..."
	 * @return
	 * @版本 1.0
	 */
	public Object queryValue(String sql) throws Exception;

	/**
	 * 获取第一行第一列的值
	 * 
	 * @param sql
	 * @param params
	 * @return
	 */
	public Object queryValue(String sql, Object[] params) throws Exception;

	/**
	 * 获取第一行第一列的值
	 * 
	 * @param sql "select field_name from table where ..."
	 * @param params
	 * @return
	 */
	public String queryString(String sql) throws Exception;

	/**
	 * 获取第一行第一列的值
	 * 
	 * @param sql "select field_name from table where ..."
	 * @param params
	 * @return
	 */
	public String queryString(String sql, Object[] params) throws Exception;

	/**
	 * 获取第一行第一列的值 如果为空，则返回0
	 * 
	 * @param sql "select field_name from table where ..."
	 * @param params
	 * @return
	 */
	public int queryInt(String sql) throws Exception;

	/**
	 * 获取第一行第一列的值 如果为空，则返回0
	 * 
	 * @param sql "select field_name from table where ..."
	 * @param params
	 * @return
	 */
	public int queryInt(String sql, Object[] params) throws Exception;

	/**
	 * 获取第一行第一列的值 如果为空，则返回0
	 * 
	 * @param sql "select field_name from table where ..."
	 * @param params
	 * @return
	 */
	public long queryLong(String sql) throws Exception;

	/**
	 * 获取第一行第一列的值 如果为空，则返回0
	 * 
	 * @param sql "select field_name from table where ..."
	 * @param params
	 * @return
	 */
	public long queryLong(String sql, Object[] params) throws Exception;

	public Clob createClob() throws Exception;

	/** Remove this instance from the session cache. */
	public void evict(Object obj);

	/** Remove this instance from the session cache. */
	public void evictList(List<?> objList);
	
	public void execute(String ddl) throws Exception;
	
	/* ************************************************** QueryReuslt ************************************************************** */
	
	/** 根据querySql执行分页查询，将查询结果过通过mapper转换为T对象后返回
	 * */
	public <T> QueryResult<T> queryEntities(QuerySQL querySql, IPagination pagination, IDataRowMapper<T> mapper) throws Exception;
	
	/** 根据querySql执行查询， 不分页， 不执行聚合查询<br>
	 * sql查询结果转为clazz时根据clazz setter(或者getter)属性上的Column注解。有Column注解，但sql中不存在，不会抛出异常；如果T 为 Map 类型，则不执行Column映射，直接返回Map对象
	 * @param <T> clazz clazz一般为使用的Column注解的POJO类型；但也可以为 Map 类型（不执行Column映射，直接返回Map对象）
	 * */
	public <T> QueryResult<T> queryEntities(Class<T> clazz, QuerySQL querySql) throws Exception;
	
	/** 根据querySql执行查询， 不分页， 执行聚合查询<br>
	 * sql查询结果转为clazz(及aggregateClazz)时根据clazz(及aggregateClazz) setter(或者getter)属性上的Column注解。有Column注解，但sql中不存在，不会抛出异常；如果T或者R为 Map 类型，则不执行Column映射，直接返回Map对象
	 * @param <T> clazz clazz一般为使用的Column注解的POJO类型；但也可以为 Map 类型（不执行Column映射，直接返回Map对象）
	 * @param <R> aggregateClazz aggregateClazz一般为使用的Column注解的POJO类型；但也可以为 Map 类型（不执行Column映射，直接返回Map对象）
	 * */
	public <T, R> QueryResultAggregation<T, R> queryEntitiesAndAggregate(Class<T> clazz, Class<R> aggregateClazz, QuerySQL querySql) throws Exception;

	/** 根据querySql执行查询， 分页， 不执行聚合查询<br>
	 * sql查询结果转为clazz时根据clazz setter(或者getter)属性上的Column注解。有Column注解，但sql中不存在，不会抛出异常；如果T或者R为 Map 类型，则不执行Column映射，直接返回Map对象
	 * @param <T> clazz clazz一般为使用的Column注解的POJO类型；但也可以为 Map 类型（不执行Column映射，直接返回Map对象）
	 * @param <R> aggregateClazz aggregateClazz一般为使用的Column注解的POJO类型；但也可以为 Map 类型（不执行Column映射，直接返回Map对象）
	 * */
	public <T> QueryResult<T> queryEntities(Class<T> clazz, QuerySQL querySql, IPagination pagination) throws Exception;
	
	/** 根据querySql执行查询， 分页， 执行聚合查询<br>
	 * sql查询结果转为clazz(及aggregateClazz)时根据clazz(及aggregateClazz) setter(或者getter)属性上的Column注解。有Column注解，但sql中不存在，不会抛出异常；如果T或者R为 Map 类型，则不执行Column映射，直接返回Map对象
	 * @param <T> clazz clazz一般为使用的Column注解的POJO类型；但也可以为 Map 类型（不执行Column映射，直接返回Map对象）
	 * @param <R> aggregateClazz aggregateClazz一般为使用的Column注解的POJO类型；但也可以为 Map 类型（不执行Column映射，直接返回Map对象）
	 * */
	public <T, R> QueryResultAggregation<T, R> queryEntitiesAndAggregate(Class<T> clazz, Class<R> aggregateClazz, QuerySQL querySql, IPagination pagination) throws Exception;
	
}
